package com.rzjm.exercise.sys.system.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rzjm.exercise.common.base.service.impl.BaseServiceImpl;
import com.rzjm.exercise.common.utils.*;
import com.rzjm.exercise.common.utils.encryp.impl.MD5Utils;
import com.rzjm.exercise.sys.core.file.domain.FileDO;
import com.rzjm.exercise.sys.core.file.service.FileService;
import com.rzjm.exercise.sys.system.dept.dao.DeptDao;
import com.rzjm.exercise.sys.system.dept.domain.DeptDO;
import com.rzjm.exercise.sys.system.user.dao.UserDao;
import com.rzjm.exercise.sys.system.user.domain.UserDO;
import com.rzjm.exercise.sys.system.user.service.UserService;
import com.rzjm.exercise.sys.vo.Tree;
import com.rzjm.exercise.sys.vo.UserVO;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Transactional
@Service
public class UserServiceImpl extends BaseServiceImpl<UserDao, UserDO> implements UserService {
    @Resource
    UserDao userMapper;
    @Resource
    DeptDao deptMapper;
    @Resource
    private FileService sysFileService;

    @Override
    public UserDO get(Integer id) {
        UserDO user = userMapper.selectById(id);
        return user;
    }

    @Override
    public int update(UserDO user) {
        int r = userMapper.updateById(user);
        return r;
    }

    @Override
    public boolean exit(Map<String, Object> params) {
        return userMapper.selectCountByMap(params) > 0;
    }

    @Override
    public int resetPwd(UserVO userVO, UserDO userDO) throws Exception {
        if (Objects.equals(userVO.getUserDO().getUserId(), userDO.getUserId())) {
            if (Objects.equals(MD5Utils.encrypt(userDO.getUsername(), userVO.getPwdOld()), userDO.getPassword())) {
                userDO.setPassword(MD5Utils.encrypt(userDO.getUsername(), userVO.getPwdNew()));
                return userMapper.updateById(userDO);
            } else {
                throw new Exception("输入的旧密码有误！");
            }
        } else {
            throw new Exception("你修改的不是你登录的账号！");
        }
    }

    @Override
    public int adminResetPwd(UserVO userVO) throws Exception {
        UserDO userDO = get(userVO.getUserId());
        if(userDO!= null){
            if ("admin".equals(userDO.getUsername())) {
                throw new Exception("超级管理员的账号不允许直接重置！");
            }
            userDO.setPassword(MD5Utils.encrypt(userDO.getUsername(), userVO.getPwdNew()));
            return userMapper.updateById(userDO);
        }
        return 0;
    }

    @Override
    public Tree<DeptDO> getTree() {
        List<Tree<DeptDO>> trees = new ArrayList<Tree<DeptDO>>();
        List<DeptDO> depts = deptMapper.selectByMap(new HashMap<String, Object>(16));
        Integer[] pDepts = listParentDept();//deptMapper.listParentDept();
        Integer[] uDepts = listAllDept();//userMapper.listAllDept();
        Integer[] allDepts = (Integer[]) ArrayUtils.addAll(pDepts, uDepts);
        for (DeptDO dept : depts) {
            if (!ArrayUtils.contains(allDepts, dept.getDeptId())) {
                continue;
            }
            Tree<DeptDO> tree = new Tree<DeptDO>();
            tree.setId(dept.getDeptId().toString());
            tree.setParentId(dept.getParentId().toString());
            tree.setText(dept.getName());
            Map<String, Object> state = new HashMap<>(16);
            state.put("opened", true);
            state.put("mType", "dept");
            tree.setState(state);
            trees.add(tree);
        }
        List<UserDO> users = userMapper.selectAllList();
        for (UserDO user : users) {
            Tree<DeptDO> tree = new Tree<DeptDO>();
            tree.setId(user.getUserId().toString());
            tree.setParentId(user.getDeptId().toString());
            tree.setText(user.getName());
            Map<String, Object> state = new HashMap<>(16);
            state.put("opened", true);
            state.put("mType", "user");
            tree.setState(state);
            trees.add(tree);
        }
        // 默认顶级菜单为０，根据数据库实际情况调整
        Tree<DeptDO> t = BuildTree.build(trees);
        return t;
    }

    private Integer[] listAllDept(){
        QueryWrapper qw = new QueryWrapper();
        qw.select("distinct dept_id");
        List<Integer> dept_id = new ArrayList<>();
        List<UserDO> list = userMapper.selectList(qw);
        list.forEach(user->{
            dept_id.add(user.getDeptId());
        });
        Integer[] integers2 = dept_id.toArray(new Integer[0]);
        return integers2;
    }

    private Integer[] listParentDept(){
        QueryWrapper qw = new QueryWrapper();
        qw.select("distinct parent_id");
        List<Integer> parent_id = new ArrayList<>();
        List<DeptDO> list = deptMapper.selectList(qw);
        list.forEach(user->{
            parent_id.add(user.getDeptId());
        });
        Integer[] integers2 = parent_id.toArray(new Integer[0]);
        return integers2;
    }


    @Override
    public UserDO getPwd(String username, String password) {
        QueryWrapper<UserDO> qw = new QueryWrapper<>();
        qw.eq("username",username);
        qw.eq("password",password);
        qw.last("limit 1");
        return userMapper.selectOne(qw);
    }

    @Override
    public int updatePersonal(UserDO userDO) {
        return userMapper.updateById(userDO);
    }

    @Override
    public Map<String, Object> updatePersonalImg(MultipartFile mfImgUrl, String avatar_data, Integer userId) throws Exception {
        String fileName = mfImgUrl.getOriginalFilename();
        fileName = FileUtil.renameToUUID(fileName);
        FileDO sysFile = new FileDO(FileType.fileType(fileName), "/"+ OssUtil.getUploadPrefix(6) + fileName, new Date());
        fileName = "/"+ OssUtil.getUploadPrefix(6) + fileName;
        //获取图片后缀
        String prefix = fileName.substring((fileName.lastIndexOf(".") + 1)).toLowerCase();
        String[] str = avatar_data.split(",");
        //获取截取的x坐标
        int x = (int) Math.floor(Double.parseDouble(str[0].split(":")[1]));
        //获取截取的y坐标
        int y = (int) Math.floor(Double.parseDouble(str[1].split(":")[1]));
        //获取截取的高度
        int h = (int) Math.floor(Double.parseDouble(str[2].split(":")[1]));
        //获取截取的宽度
        int w = (int) Math.floor(Double.parseDouble(str[3].split(":")[1]));
        //获取旋转的角度
        int r = Integer.parseInt(str[4].split(":")[1].replaceAll("}", ""));
        try {
            BufferedImage cutImage = ImageUtils.cutImage(mfImgUrl, x, y, w, h, prefix);
            BufferedImage rotateImage = ImageUtils.rotateImage(cutImage, r);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageIO.write(rotateImage, prefix, out);
            //转换后存入数据库
//            byte[] b = out.toByteArray();
            if (!mfImgUrl.isEmpty()) {
                if ("jpeg".equals(prefix) || "jpg".equals(prefix) || "png".equals(prefix) || "gif".equals(prefix)) {
                    try {
                        InputStream inputStream = mfImgUrl.getInputStream();
                        if (inputStream != null) {
                            int upload_type = OssUtil.TYPE_FACEURLS_PHOTOS;
                            OssUtil.upload(inputStream, fileName, upload_type);
                            try {
                                inputStream.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
//            FileUtil.uploadFile(b, bootdoConfig.getUploadPath(), fileName);
        } catch (Exception e) {
            throw new Exception("图片裁剪错误！！");
        }
        Map<String, Object> result = new HashMap<>();
        if (sysFileService.save(sysFile)) {
            UserDO userDO = new UserDO();
            userDO.setUserId(userId);
            if (userMapper.updateById(userDO) > 0) {
                result.put("url", sysFile.getUrl());
            }
        }
        return result;
    }

    @Override
    public List<UserDO> getPageByUserId(Map<String, Object> map) {
        return baseDao.getPageByUserId(map);
    }

    @Override
    public Integer getCountBySysUserId(Map<String, Object> map) {
        return baseDao.getCountBySysUserId(map);
    }

    @Override
    public List<UserDO> getBaoBaoListByUserId(Page page, Map<String, Object> map) {
        return baseDao.getBaoBaoListByUserId(page, map);
    }

    @Override
    @Transactional
    public int register(UserDO user) {
        int result = userMapper.insert(user);
        return result;
    }
}
